#ifndef __PATH_UTILS__
#define __PATH_UTILS__

#include "directory.h"
#include "volume.h"
#include "kfile.h"

namespace xm 
{
	struct b_path_t
	{
		std::string		text;
		std::string		part;
		const char*		txtp;
		b_path_t() : txtp(){}
		const char * cptr()
		{
			return text.c_str();
		}
		void go_head()
		{
			txtp = text.c_str();
		}
		bool at_tail()
		{
			return *txtp == 0;
		}
		virtual const char * go_next_part() 
		{ 
			return 0;
		}
	};
	struct win32_traits
	{
		static bool is_slash( char ch ) 
		{
			return ch == '\\' || ch == '/';
		}
		static bool is_valid_char( char ch, bool in_file_name = false )
		{
			switch( ch )
			{
			case '*': case '?': case '\"': case '<': case '>': case '|':
				return false;
			case ':': case '\\': case '/':
				return in_file_name ? false : true;
			}
			return true;
		}
	};
	struct nt_traits
	{
		static bool is_slash( char ch ) 
		{
			return ch == '\\';
		}
		static bool is_valid_char( char ch, bool in_file_name = false )
		{
			if( !in_file_name ) return true;
			return is_slash(ch) == false;
		}
	};
	template < class T >
	struct xx_path_t : b_path_t
	{
		typedef T	Traits;
		size_t skip_slash( const char * & p )
		{
			const char * k = p;
			for( ; *p && T::is_slash(*p); ++ p );
			return  p - k;
		}
		const char * skip_not_slash( const char * p )
		{
			for( ; *p && !T::is_slash(*p); ++ p );
			return p;
		}
		bool create( const char * p, size_t len = 0 )
		{
			text.clear();
			if( !len ) len = 0x10000;
			const char * last = p + len;
			for( ; *p && p < last; ++ p )
			{
				if( !T::is_valid_char(*p) )
					return false;

				if( T::is_slash(*p) ) 
					text.push_back('\\');
				else 
					text.push_back( tolower(*p) );
			}
			txtp = text.c_str();
			return true;
		}
		const char * go_next_part() 
		{
			if( !*txtp ) return 0;
			size_t c = skip_slash(txtp);
			if( !*txtp ) return c ? "\\" : NULL;
			const char * ne = skip_not_slash(txtp);
			part.assign( txtp, ne );
			txtp = ne;
			return part.c_str();
		}
		const char * get_last()
		{
			const char * first = text.c_str();
			const char * last = first + text.size();
			for( -- last; last >= first; -- last )
			{
				if( T::is_slash(*last) )
					break;
			}
			++ last;
			return last;
		}
	};

	typedef xx_path_t<nt_traits>	nt_path_t;
	typedef xx_path_t<win32_traits>	w32_path_t;
};

#endif